#!/usr/bin/env node

require('dotenv').config();
const Client = require('ftp');
const chalk = require('chalk');
const net = require('net');

class AdvancedFTPDiagnose {
    constructor() {
        this.host = process.env.FTP_HOST;
        this.port = parseInt(process.env.FTP_PORT) || 21;
        this.user = process.env.FTP_USER;
        this.password = process.env.FTP_PASSWORD;
    }

    async run() {
        console.log(chalk.blue('🔬 高级FTP诊断工具'));
        console.log(chalk.gray('=' .repeat(50)));
        
        // 步骤1: 测试PASV命令
        await this.testPasvCommand();
        
        // 步骤2: 测试PORT命令 
        await this.testPortCommand();
        
        // 步骤3: 测试数据端口连接
        await this.testDataPorts();

        console.log(chalk.blue('\n💡 诊断建议:'));
        this.showAdvancedSuggestions();
    }

    async testPasvCommand() {
        console.log(chalk.yellow('1. 测试PASV命令获取数据端口...'));
        
        return new Promise((resolve) => {
            const client = new Client();
            client.on('ready', () => {
                console.log(chalk.green('  ✓ 控制连接建立'));
                
                // 手动发送PASV命令
                client._send('PASV', (err, text, code) => {
                    if (err) {
                        console.log(chalk.red(`  ❌ PASV命令失败: ${err.message}`));
                    } else {
                        console.log(chalk.green(`  ✓ PASV响应: ${text}`));
                        
                        // 解析PASV响应获取IP和端口
                        const match = text.match(/\((\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\)/);
                        if (match) {
                            const ip = `${match[1]}.${match[2]}.${match[3]}.${match[4]}`;
                            const port = (parseInt(match[5]) * 256) + parseInt(match[6]);
                            console.log(chalk.cyan(`  📍 数据连接地址: ${ip}:${port}`));
                            
                            // 测试数据端口连接
                            this.testSpecificPort(ip, port);
                        }
                    }
                    client.end();
                    resolve();
                });
            });

            client.on('error', (err) => {
                console.log(chalk.red(`  ❌ 连接失败: ${err.message}`));
                resolve();
            });

            client.connect({
                host: this.host,
                port: this.port,
                user: this.user,
                password: this.password,
                passive: true
            });
        });
    }

    async testPortCommand() {
        console.log(chalk.yellow('\n2. 测试PORT命令...'));
        
        return new Promise((resolve) => {
            // 创建本地监听端口
            const server = net.createServer();
            
            server.listen(0, '0.0.0.0', () => {
                const localPort = server.address().port;
                console.log(chalk.cyan(`  📍 本地监听端口: ${localPort}`));
                
                const client = new Client();
                client.on('ready', () => {
                    // 获取本地IP（简化处理）
                    const localIP = '127.0.0.1'; // 实际应该获取外网IP
                    const portHigh = Math.floor(localPort / 256);
                    const portLow = localPort % 256;
                    const portCmd = `PORT ${localIP.replace(/\./g, ',')},${portHigh},${portLow}`;
                    
                    client._send(portCmd, (err, text, code) => {
                        if (err) {
                            console.log(chalk.red(`  ❌ PORT命令失败: ${err.message}`));
                        } else {
                            console.log(chalk.green(`  ✓ PORT响应: ${text}`));
                        }
                        
                        client.end();
                        server.close();
                        resolve();
                    });
                });

                client.on('error', (err) => {
                    console.log(chalk.red(`  ❌ 连接失败: ${err.message}`));
                    server.close();
                    resolve();
                });

                client.connect({
                    host: this.host,
                    port: this.port,
                    user: this.user,
                    password: this.password,
                    passive: false
                });
            });
        });
    }

    async testSpecificPort(ip, port) {
        console.log(chalk.yellow(`  测试数据端口 ${ip}:${port} 连接性...`));
        
        return new Promise((resolve) => {
            const socket = new net.Socket();
            const timeout = 5000;
            
            socket.setTimeout(timeout);
            
            socket.on('connect', () => {
                console.log(chalk.green(`  ✓ 数据端口 ${ip}:${port} 连接成功`));
                socket.destroy();
                resolve(true);
            });
            
            socket.on('timeout', () => {
                console.log(chalk.red(`  ❌ 数据端口 ${ip}:${port} 连接超时`));
                socket.destroy();
                resolve(false);
            });
            
            socket.on('error', (err) => {
                console.log(chalk.red(`  ❌ 数据端口 ${ip}:${port} 连接失败: ${err.message}`));
                socket.destroy();
                resolve(false);
            });
            
            socket.connect(port, ip);
        });
    }

    async testDataPorts() {
        console.log(chalk.yellow('\n3. 测试常见数据端口范围...'));
        
        // 测试常见的FTP数据端口范围
        const commonPorts = [20, 21000, 30000, 40000, 50000];
        
        for (const port of commonPorts) {
            await this.testSpecificPort(this.host, port);
        }
    }

    showAdvancedSuggestions() {
        console.log(chalk.cyan('🔧 高级解决方案:'));
        console.log(chalk.cyan('1. 网络层问题:'));
        console.log(chalk.gray('   • 检查本地防火墙/路由器是否阻止FTP数据端口'));
        console.log(chalk.gray('   • 确认ISP是否限制FTP数据连接'));
        console.log(chalk.gray('   • 尝试使用VPN或代理'));
        
        console.log(chalk.cyan('\n2. 服务器端问题:'));
        console.log(chalk.gray('   • 服务器防火墙可能只开放了21端口'));
        console.log(chalk.gray('   • PASV模式端口范围配置可能有问题'));
        console.log(chalk.gray('   • 联系服务器管理员确认FTP配置'));
        
        console.log(chalk.cyan('\n3. 备选解决方案:'));
        console.log(chalk.gray('   • 使用SFTP替代FTP (如果服务器支持)'));
        console.log(chalk.gray('   • 使用其他文件传输方式 (rsync, scp等)'));
        console.log(chalk.gray('   • 请求管理员开启FTP数据端口范围'));
        
        console.log(chalk.yellow('\n建议联系服务器管理员检查以下配置:'));
        console.log(chalk.gray('• Pure-FTPd的PassivePortRange配置'));
        console.log(chalk.gray('• 服务器防火墙的FTP数据端口开放'));
        console.log(chalk.gray('• 是否支持SFTP (端口22)'));
    }
}

if (require.main === module) {
    const diagnose = new AdvancedFTPDiagnose();
    diagnose.run().catch(console.error);
}

module.exports = AdvancedFTPDiagnose;